#include<bits/stdc++.h>
using namespace std;
const int N = 210;
int f[N][N];
int rk[N][N];
vector<tuple<int,int,int>> es;
struct cmp{
    int S;
    cmp(int s){
        S = s;
    }
    bool operator()(int x,int y){
        return f[S][x] < f[S][y];
    }
};
int main(){
    freopen("center.in","r",stdin);
    freopen("center.out","w",stdout);
    int n,m;
    cin>>n>>m;
    memset(f,0x3f,sizeof(f));
    for(int i = 1;i<=n;i++){
        f[i][i] = 0;
    }
    for(int i = 1;i<=m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        es.push_back(make_tuple(u,v,w));
        f[u][v] = min(w,f[u][v]);
        f[v][u] = min(w,f[v][u]);
    }
    for(int k = 1;k <= n;k++){
        for(int i = 1;i<=n;i++){
            for(int j = 1;j <= n;j++){
                f[i][j] = min(f[i][j],f[i][k] + f[k][j]);
            }
        }
    }
    double ans = 1e9;
    for(int i = 1;i<=n;i++){
        for(int j = 1;j <= n;j++){
            rk[i][j] = j;
        }
        sort(rk[i] + 1,rk[i] + 1 + n,cmp(i));
        ans = min(ans,1.0*f[i][rk[i][n]]);
    }
    for(tuple<int,int,int> tp : es){
        int u,v,w;
        tie(u,v,w) = tp;
        int nxt = 0;
        for(int i = n;i >= 1;i--){
            if((f[u][rk[u][i]] + nxt + w)/2.0 >= max(f[u][rk[u][i]],nxt)){
                ans = min(ans,(f[u][rk[u][i]] + nxt + w)/2.0);
            }
            nxt = max(f[v][rk[u][i]],nxt);
        }
    }
    cout<<fixed<<setprecision(2)<<ans<<'\n';
}